package com.campus.filter;

import com.alibaba.fastjson2.JSON;
import com.campus.common.CampusWall;
import com.campus.common.Result;
import com.campus.entity.Users;
import com.campus.utils.TokenUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.io.IOException;

/**
 * 过滤器
 */
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Component
@Slf4j
public class WebFilterConfig implements Filter {
    public static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();
    @Autowired
    private TokenUtils tokenUtils;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //获取请求路径
        String requestURI = request.getRequestURI();
        log.info("访问路径:" + requestURI);
        String token = null;
        Users currentUser = null;
        //放行路径
        String releaseUrl[] = {
                "/api/user/register",
                "/api/user/login",
                "/api/user/forgot-password/send-code",
                "/api/user/captcha",
                "/api/user/register/send-code",
                "/api/user/forgot-password/verify-code",
                "/api/user/forgot-password/reset",
                "/api/file/upload",
                "/api/user/avatar/upload",
                "/api/user/avatar/**",
//                "/api/post/**",  // 放行所有帖子相关请求
//                "/api/file/**"   // 添加这行，放行所有文件访问请求


        };
        // 放行 OPTIONS 请求（CORS 预检请求）
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        //这里是匹配的路径放行
        if (checkPath(releaseUrl, requestURI)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        //如果路径不一样要看用户是否登录了
        token = request.getHeader(CampusWall.CAMPUS_TOKEN);
        if (token == null || token.trim().isEmpty()) {
            // 尝试从参数获取
            token = request.getParameter("token");
            log.info("参数中的 Token: {}", token);
            if (token == null || token.trim().isEmpty()) {
                //这里没有的话从cookie中找
                Cookie[] cookies = request.getCookies();
                if (cookies != null) {
                    token = getCookieName(cookies, "token");
                }
            }
        }


        if (token != null) {
            token = tokenUtils.getToken(token);
            currentUser = tokenUtils.getCurrentUser(token);
            String redisToken = stringRedisTemplate.opsForValue().get(currentUser.getUsername());
            if (!token.equals(redisToken)) {
                response.getWriter().write(JSON.toJSONString(Result.err(Result.CODE_401, "未登录")));
                return;
            }

            if (currentUser != null && currentUser.getStatus() == 1) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
        }
        if (token == null || token.trim().isEmpty()) {
            log.info(JSON.toJSONString(Result.err(Result.CODE_500, "token不能为空")));
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write(JSON.toJSONString(Result.err(Result.CODE_401, "未登录")));
            return;
        }
    }

    public boolean checkPath(String[] urls, String requestURI) {
        for (String url : urls
        ) {
            if (ANT_PATH_MATCHER.match(url, requestURI)) {
                return true;
            }
        }
        return false;
    }

    public String getCookieName(Cookie[] cookies, String key) {
        String token;
        if (cookies != null) {
            for (int i = 0; i < cookies.length; i++) {
                if (cookies[i].getName().equals(key)) {
                    return cookies[i].getValue();
                }
            }
        }
        return null;
    }
}